﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace Avanzis.QueryBuilder.Fluent
{
    ///<summary>
    ///</summary>
    public class Fields<T> : IEnumerable<SqlField> where T : class
    {
        private readonly SqlFieldCollection fieldCollection;

        ///<summary>
        ///</summary>
        public Fields()
        {
            fieldCollection = new SqlFieldCollection();
        }

        #region AddField

       
        ///<summary>
        ///</summary>
        ///<param name = "expression"></param>
        ///<returns></returns>
        public Fields<T> AddField(string expression)
        {
            fieldCollection.Add(expression);
            return this;
        }


        ///<summary>
        ///</summary>
        ///<param name = "expression"></param>
        ///<param name = "alias"></param>
        ///<returns></returns>
        public Fields<T> AddField(string expression, string alias)
        {
            fieldCollection.Add(expression, alias);

            return this;
        }

        ///<summary>
        ///</summary>
        ///<param name = "expression"></param>
        ///<returns></returns>
        public Fields<T> AddField(Expression<Func<T, object>> expression)
        {
            var stringExpression = FluentHelper.ParseProperty(expression);
            fieldCollection.Add(stringExpression);
            return this;
        }

        ///<summary>
        ///</summary>
        ///<param name = "expression"></param>
        ///<param name = "propertyExpression"></param>
        ///<returns></returns>
        public Fields<T> AddField(string expression, Expression<Func<T, object>> propertyExpression)
        {
            var alias = FluentHelper.ParseProperty(propertyExpression);
            fieldCollection.Add(expression, alias);
            return this;
        }

        #endregion

        #region AddField<K>
        
        ///<summary>
        ///</summary>
        ///<param name = "expression"></param>
        ///<typeparam name = "K"></typeparam>
        ///<returns></returns>
        public Fields<T> AddField<K>(Expression<Func<K, object>> expression)
        {
            SqlField field = FluentHelper.GetField(expression);
            fieldCollection.Add(field);

            return this;
        }

        ///<summary>
        ///</summary>
        ///<param name = "propertyExpression"></param>
        ///<param name = "aliasExpression"></param>
        ///<typeparam name = "K"></typeparam>
        ///<returns></returns>
        public Fields<T> AddField<K>(Expression<Func<K, object>> propertyExpression, Expression<Func<T, object>> aliasExpression)
        {
            SqlField field = FluentHelper.GetField(propertyExpression, aliasExpression);
            fieldCollection.Add(field);
            return this;
        }

        ///<summary>
        ///</summary>
        ///<param name = "expression"></param>
        ///<typeparam name = "K"></typeparam>
        ///<returns></returns>
        public Fields<T> AddField<K>(string expression)
        {
            SqlField field = FluentHelper.GetField<K>(expression);

            fieldCollection.Add(field);
            return this;
        }

        #endregion

        public IEnumerator<SqlField> GetEnumerator()
        {
            return fieldCollection.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}